#coding=utf-8

import re
import os
import datetime
import json
import zipfile

def mzccDoAnalysis(problemDic):

    # 生成目录
    resultPath = "./Results";
    if False == os.path.exists(resultPath):
        os.mkdir(resultPath);

    analysisPath = resultPath + "/Analysis";
    if False == os.path.exists(analysisPath):
        os.mkdir(analysisPath);

    # 概要信息
    fp = open(analysisPath + "/mzccSummary.txt", "w");
    fp.truncate();
    summaryTuple = mzccSummaryInfoFromProblemDic(problemDic);
    summaryStr = "该次检查了" + str(summaryTuple[0]) + "个文件" \
    "(问题文件" + str(summaryTuple[1]) + "个，无问题文件" + str(summaryTuple[2]) + "个)\n";
    summaryStr += "共发现了" + str(summaryTuple[3]) + "个问题,分为" + str(summaryTuple[4]) + "种类型\n";
    print >> fp, summaryStr;
    fp.close();

    # 问题数量统计
    fp = open(analysisPath + "/mzccProblemCounter.txt", "w");
    fp.truncate();
    counterArray = mzccProblemCounterInfoFromProblemDic(problemDic);
    top3Num = 0;
    top3Count = 0;
    for tmpTuple in counterArray:
        print >> fp, str(tmpTuple[0]);
        print >> fp, "存在问题：" + str(tmpTuple[1]) + "个";
        if top3Count < 3:
            top3Count += 1;
            top3Num += tmpTuple[1];

    print >> fp, "\n【概览】"
    print >> fp, "存在问题" + str(len(counterArray))+ "类";
    print >> fp, "其中，数量排名前3的问题占问题总数的" + str(round((100 * top3Num / float(summaryTuple[3])), 2)) + "%";
    fp.close();

    # 检查文件列表
    fp = open(analysisPath + "/mzccChekedFileList.txt", "w");
    fp.truncate();
    tmpFileArray = mzccCheckedFileListFromProblemDic(problemDic);
    for tmpPath in tmpFileArray:
        print >> fp, tmpPath;
    print >> fp, "检查文件总数: " + str(len(tmpFileArray)) + "个";
    fp.close();

    # 检查的问题文件列表
    fp = open(analysisPath + "/mzccChekedProblemFileList.txt", "w");
    fp.truncate();
    tmpFileArray = mzccProblemFileListFromProblemDic(problemDic);
    for tmpPath in tmpFileArray:
        print >> fp, tmpPath;
    print >> fp, "存在规范问题的文件总数: " + str(len(tmpFileArray)) + "个";
    fp.close();

    # 检查的无问题文件列表
    fp = open(analysisPath + "/mzccChekedNoPorblemFileList.txt", "w");
    fp.truncate();
    tmpFileArray = mzccNoProblemFileListFromProblemDic(problemDic);
    for tmpPath in tmpFileArray:
        print >> fp, tmpPath;
    print >> fp, "没有规范问题的文件总数: " + str(len(tmpFileArray)) + "个";
    fp.close();

    # 问题详情列表
    fp = open(resultPath + "/mzccProblemDetail.txt", "w");
    fp.truncate();

    curTime = datetime.datetime.now()
    curTime.strftime('%Y-%m-%d %H:%M:%S')
    print >> fp, "检测时间：";
    print >> fp, curTime, "\n";
    if 0 == len(problemDic):
        print >> fp, "很棒哦，没有检测到任何问题！";

    for tmpPath in problemDic:
        problemList = problemDic[tmpPath];
        fileTumple = os.path.split(tmpPath)

        if 0 == len(problemList):
            continue;

        print >> fp, "[Dir]  " + fileTumple[0];
        print >> fp, "[File] " + fileTumple[1];
        for tmpProblem in problemList:
            print >> fp, tmpProblem.formatStr();
        print >> fp, "";
    print >> fp, "\n【概览】"
    print >> fp, summaryStr;
    fp.close();

'''
' 输出检查结果的概要信息
' 输出：
'  tuple（检查文件数、问题文件数、无问题文件数、问题数、问题类型数）
'''
def mzccSummaryInfoFromProblemDic(problemDic):

    fileNum = 0;
    problemFileNum = 0;
    noProblemFileNum = 0;

    problemNum = 0;
    problemArray = [];

    for tmpPath in problemDic:

        problemList = problemDic[tmpPath];

        fileNum = fileNum + 1;
        problemNum += len(problemList);

        if 0 == len(problemList):
            noProblemFileNum = noProblemFileNum + 1;
        else:
            problemFileNum = problemFileNum + 1;

        for tmpProblem in problemList:
            if tmpProblem.ruleId in problemArray:
                continue;
            else:
                problemArray.append(tmpProblem.ruleId);

    return (fileNum, problemFileNum, noProblemFileNum, problemNum, len(problemArray));

'''
' 输出每个问题的发生次数
' 输出：
'  array（按照问题发生个数排序，每个item是一个tuple(问题描述、问题个数)) 
'''
def mzccProblemCounterInfoFromProblemDic(problemDic):

    problemCounterDic = {};

    for tmpPath in problemDic:
        problemList = problemDic[tmpPath];

        for tmpProblem in problemList:

            if tmpProblem.desc in problemCounterDic:
                problemCounterDic[tmpProblem.desc] += 1;
            else:
                problemCounterDic[tmpProblem.desc] = 1;

    sortTupleArray = sorted(problemCounterDic.items(), key=lambda d: d[1], reverse=True);

    return sortTupleArray;

'''
' 输出该次检查的文件列表
' 输出：
'  array（每个item是一个文件路径）
'''
def mzccCheckedFileListFromProblemDic(problemDic):

    fileList = [];

    for tmpPath in problemDic:
        fileList.append(tmpPath);

    return fileList;

'''
' 输出该次检查的问题文件列表
' 输出：
'  array（每个item是一个文件路径）
'''
def mzccProblemFileListFromProblemDic(problemDic):

    fileList = [];

    for tmpPath in problemDic:
        if 0 != len(problemDic[tmpPath]):
            fileList.append(tmpPath);

    return fileList;

'''
' 输出该次检查的无问题文件列表
' 输出：
'  array（每个item是一个文件路径）
'''
def mzccNoProblemFileListFromProblemDic(problemDic):

    fileList = [];

    for tmpPath in problemDic:
        if 0 == len(problemDic[tmpPath]):
            fileList.append(tmpPath);

    return fileList;

# ProblemDic --> JSON Dic

'''
' 将prodblemDic转换成结果文件：
' 输入：
'  checkType : 检查类型（0: 文件检查，1: 文件列表检查，2: 目录检查）
'  checkPath : 检查目录（只有目录检查生效）
'  problemDic : 问题字典
' 输出(结果字典)：
'  check_time : 检查时间，如"2017-02-04 13:43:23"
'  check_type : 检查类型（0: 文件检查，1: 文件列表检查，2: 目录检查）
'  check_path : 检查目录（只有目录检查生效）
'  problem_num : 问题数量
'  problem_info : 问题详情
'''
def mzccWriteResult(checkType,
                    checkPath,
                    problemDic):

    # 问题文件
    tmpFilePath = "./Results/mzccCheckResult.json";
    fp = open(tmpFilePath, "w");
    fp.truncate();

    tarDic = {};

    # check_time
    curTime = datetime.datetime.now()
    tarDic["check_time"] = curTime.strftime('%Y-%m-%d %H:%M:%S');

    # check_type
    if 0 != len(checkType):
        tarDic["check_type"] = checkType;

    # check_path
    if 0 != len(checkPath):
        tarDic["check_path"] = checkPath;

    # problem_num
    # problem_info
    infoDic = {};
    problemNum = 0;
    for tmpPath in problemDic:
        problemList = problemDic[tmpPath];
        tmpList = [];
        for tmpProblem in problemList:
            tmpProDic = tmpProblem.simpleDicInfo();
            tmpList.append(tmpProDic);
            problemNum += 1;
        infoDic[tmpPath] = tmpList;
    tarDic["problem_num"] = str(problemNum);
    tarDic["problem_info"] = infoDic;

    json.dump(tarDic, fp);
    fp.close();

